Get OD data from IMOB

The biclaR project hosts several open datasets useful for this spatial analysis relateg with transportation in the Lisbon Metro region.

TRIPSall = readRDS(url("https://github.com/U-Shift/biclar/releases/download/0.0.1/TRIPSmode_municipal.Rds"))

TRIPSall[TRIPSall == "Setubal"] = "Setúbal" #rename

knitr::kable(head(TRIPSall)) # have a look at data
Origem Destino modo viagens
Alcochete Alcochete Bike 320.54
Alcochete Alcochete Car 12432.32
Alcochete Alcochete Motorcycle 52.12
Alcochete Alcochete Other 6.85
Alcochete Alcochete Transit 834.06
Alcochete Alcochete Walk 6914.64

Remove intrazonal trips and group by Private vs Public

# With all modes
TRIPSinter = TRIPSall |>
  filter(Origem != Destino) |> # remove internal trips
  as.data.frame() |> 
  group_by(Origem, Destino) |> 
  summarise(viagens = sum(viagens)) |> 
  ungroup() |> 
  od_oneway() # sum the O with D - doesn't matter the start and end point for vizualization purpouses

  
# With variables of public or private modes
TRIPSvs = TRIPSall |>
  filter(Origem != Destino) |> # remove internal trips
  as.data.frame() |> 
  mutate(Tipo = recode(modo,  # recode in TI and TC
         Bike = "TIndividual",
         Car = "TIndividual",
         Motorcycle = "TIndividual",
         Other = "TIndividual",
         Transit = "TColetivo",
         Walk = "TIndividual")) |> 
  group_by(Origem, Destino, Tipo) |> 
  summarise(viagens = sum(viagens)) |> 
  ungroup() |> 
  pivot_wider(names_from = Tipo,
              values_from = viagens)

TRIPSvs[is.na(TRIPSvs)] = 0 # há casos em que não há viagens registadas entre municípios
TRIPSvs = od_oneway(TRIPSvs) # magia para somar O-D com D-O


knitr::kable(head(TRIPSvs)) # viagens separadas por TI e TC
Origem Destino TIndividual TColetivo
Alcochete Almada 1277.85 48.88
Alcochete Amadora 215.71 162.54
Alcochete Barreiro 1710.42 10.28
Alcochete Cascais 228.50 0.00
Alcochete Lisboa 4036.93 1612.31
Alcochete Loures 948.36 0.00

A total of 5.3 million trips are made daily in the AML, of which 1823 thousand are intercity.

Get AML maps

MUNICIPIOSgeo = readRDS(url("https://github.com/U-Shift/biclar/releases/download/0.0.1/MUNICIPIOSgeo.Rds"))
MUNICIPIOSgeo$Concelho[MUNICIPIOSgeo$Concelho == "Setubal"] = "Setúbal"

AML_dtcc = readRDS(url("https://github.com/U-Shift/biclar/releases/download/0.0.1/ZONAMENTO_imob.Rds"))
AML_dtcc = AML_dtcc |> select(DTMN, DTMN_DSG) |> unique()

CENTROIDS = readRDS(url("https://github.com/U-Shift/biclar/releases/download/0.0.1/CENTROIDS_municipios.Rds"))
CENTROIDS = CENTROIDS |>
  left_join(AML_dtcc, by = c("DTMN11" = "DTMN")) |>
  select(DTMN_DSG, geometry) |>
  filter(DTMN_DSG != "Montijo")

MONTIJO = sf::st_read("geo/Montijo.geojson", quiet = TRUE) # Porque o centro das duas parts do Montijo não calha dentro do Montijo
CENTROIDS = rbind(CENTROIDS, MONTIJO)

Make maps

Use stplanr to create the desire lines.

LINHASod = od2line(flow = TRIPSinter,
                   zones = CENTROIDS,
                   zone_code = "DTMN_DSG") |> 
  filter(viagens >= 1000)
LINHASod_noLX = LINHASod |> filter(Origem != "Lisboa" & Destino != "Lisboa")

LINHASod_TI = od2line(flow = TRIPSvs |> select(-TColetivo),
                      zones = CENTROIDS,
                      zone_code = "DTMN_DSG") |> 
  filter(TIndividual > 1000)
LINHASod_TI_noLX = LINHASod_TI |> filter(Origem != "Lisboa" & Destino != "Lisboa")

LINHASod_TC = od2line(flow = TRIPSvs |> select(-TIndividual),
                      zones = CENTROIDS,
                      zone_code = "DTMN_DSG") |> 
  filter(TColetivo > 1000)
LINHASod_TC_noLX = LINHASod_TC |> filter(Origem != "Lisboa" & Destino != "Lisboa")

All Trips

Including Lisbon

m1 =  tm_shape(MUNICIPIOSgeo) +
  tm_borders(col = "grey") +
  tm_shape(LINHASod %>% filter(viagens >=5000)) +
  tm_lines("viagens",
           palette = viridis::magma(n = 4, direction = -1),
           breaks = c(5000, 10000, 50000, 100000, 161000),
           lwd = "viagens",
           scale = 30,
           title.col = "Viagens intermunicipais") +
  tm_shape(CENTROIDS) +
  tm_text("DTMN_DSG", size = 0.8, col = "gray25")
m1

Excluding Lisbon

m2 = tm_shape(MUNICIPIOSgeo) +
  tm_borders(col = "grey") +
  tm_shape(LINHASod_noLX %>% filter(viagens >=3000)) +
  tm_lines("viagens",
           palette = viridis::magma(n = 4, direction = -1),
           breaks = c(3000, 10000, 30000, 60000, 73000),
           lwd = "viagens",
           scale = 30,
           title.col = "Viagens intermunicipais, fora de Lisboa") +
  tm_shape(CENTROIDS) +
  tm_text("DTMN_DSG", size = 0.8, col = "gray25")
m2

Only Public Transit trips

Including Lisbon

m3 = tm_shape(MUNICIPIOSgeo) +
  tm_borders(col = "grey") +
  tm_shape(LINHASod_TC %>% filter(TColetivo >=3000)) +
  tm_lines("TColetivo",
           palette = viridis::viridis(n = 4, direction = -1),
           breaks = c(3000, 5000, 10000, 25000, 50000),
           lwd = "TColetivo",
           scale = 30,
           title.col = "Viagens intermunicipais, em Transporte Coletivo") +
  tm_shape(CENTROIDS) +
  tm_text("DTMN_DSG", size = 0.8, col = "gray25")
m3

Excluding Lisbon

m4 = tm_shape(MUNICIPIOSgeo) +
  tm_borders(col = "grey") +
  tm_shape(LINHASod_TC_noLX %>% filter(TColetivo >=2000)) +
  tm_lines("TColetivo",
           palette = viridis::viridis(n = 4, direction = -1),
           breaks = c(2000, 4000, 7000, 10000, 13000),
           lwd = "TColetivo",
           scale = 30,
           title.col = "Viagens intermunicipais, em Transporte Coletivo (fora Lx)") +
  tm_shape(CENTROIDS) +
  tm_text("DTMN_DSG", size = 0.8, col = "gray25")
m4

Only Private trips

Including Lisbon

m5 = tm_shape(MUNICIPIOSgeo) +
  tm_borders(col = "grey") +
  tm_shape(LINHASod_TI %>% filter(TIndividual >=5000)) +
  tm_lines("TIndividual",
           palette = viridis::plasma(n = 4, direction = -1),
           breaks = c(5000, 20000, 50000, 100000, 115000),
           lwd = "TIndividual",
           scale = 30,
           title.col = "Viagens intermunicipais, em Transporte Individual") +
  tm_shape(CENTROIDS) +
  tm_text("DTMN_DSG", size = 0.8, col = "gray25")
m5

Excluding Lisbon

m6 = tm_shape(MUNICIPIOSgeo) +
  tm_borders(col = "grey") +
  tm_shape(LINHASod_TI_noLX %>% filter(TIndividual >=3000)) +
  tm_lines("TIndividual",
           palette = viridis::plasma(n = 4, direction = -1),
           breaks = c(3000, 10000, 25000, 50000, 65000),
           lwd = "TIndividual",
           scale = 30,
           title.col = "Viagens intermunicipais, em Transporte Individual (fora Lx)") +
  tm_shape(CENTROIDS) +
  tm_text("DTMN_DSG", size = 0.8, col = "gray25")
m6
LS0tCnRpdGxlOiAiVHJpcHMgaW4gQU1MIHdpdGggbWFwcyIKYXV0aG9yOiAiUiBGw6lsaXgiCmRhdGU6ICJNUUFUIDIwMjMiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDQKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiAiaGlkZSIKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFKQpgYGAKCmBgYHtyIGxpYnJhcmllcywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc3RwbGFucikKbGlicmFyeSh0bWFwKQp0bWFwX21vZGUoInZpZXciKQpgYGAKCgojIyBHZXQgT0QgZGF0YSBmcm9tIElNT0IKClRoZSBbKipiaWNsYVIqKl0oaHR0cHM6Ly9iaWNsYXIudG1sbW9iaWxpZGFkZS5wdC8pIHByb2plY3QgaG9zdHMgc2V2ZXJhbCBbb3BlbiBkYXRhc2V0c10oaHR0cHM6Ly9naXRodWIuY29tL1UtU2hpZnQvYmljbGFyL3JlbGVhc2VzL3RhZy8wLjAuMSkgdXNlZnVsIGZvciB0aGlzIHNwYXRpYWwgYW5hbHlzaXMgcmVsYXRlZyB3aXRoIHRyYW5zcG9ydGF0aW9uIGluIHRoZSBMaXNib24gTWV0cm8gcmVnaW9uLgoKYGBge3IgcmVhZGRhdGF9ClRSSVBTYWxsID0gcmVhZFJEUyh1cmwoImh0dHBzOi8vZ2l0aHViLmNvbS9VLVNoaWZ0L2JpY2xhci9yZWxlYXNlcy9kb3dubG9hZC8wLjAuMS9UUklQU21vZGVfbXVuaWNpcGFsLlJkcyIpKQoKVFJJUFNhbGxbVFJJUFNhbGwgPT0gIlNldHViYWwiXSA9ICJTZXTDumJhbCIgI3JlbmFtZQoKa25pdHI6OmthYmxlKGhlYWQoVFJJUFNhbGwpKSAjIGhhdmUgYSBsb29rIGF0IGRhdGEKYGBgCgpSZW1vdmUgKippbnRyYXpvbmFsKiogdHJpcHMgYW5kIGdyb3VwIGJ5IFByaXZhdGUgdnMgUHVibGljCgpgYGB7ciB0cmlwc2NsZWFufQojIFdpdGggYWxsIG1vZGVzClRSSVBTaW50ZXIgPSBUUklQU2FsbCB8PgogIGZpbHRlcihPcmlnZW0gIT0gRGVzdGlubykgfD4gIyByZW1vdmUgaW50ZXJuYWwgdHJpcHMKICBhcy5kYXRhLmZyYW1lKCkgfD4gCiAgZ3JvdXBfYnkoT3JpZ2VtLCBEZXN0aW5vKSB8PiAKICBzdW1tYXJpc2UodmlhZ2VucyA9IHN1bSh2aWFnZW5zKSkgfD4gCiAgdW5ncm91cCgpIHw+IAogIG9kX29uZXdheSgpICMgc3VtIHRoZSBPIHdpdGggRCAtIGRvZXNuJ3QgbWF0dGVyIHRoZSBzdGFydCBhbmQgZW5kIHBvaW50IGZvciB2aXp1YWxpemF0aW9uIHB1cnBvdXNlcwoKICAKIyBXaXRoIHZhcmlhYmxlcyBvZiBwdWJsaWMgb3IgcHJpdmF0ZSBtb2RlcwpUUklQU3ZzID0gVFJJUFNhbGwgfD4KICBmaWx0ZXIoT3JpZ2VtICE9IERlc3Rpbm8pIHw+ICMgcmVtb3ZlIGludGVybmFsIHRyaXBzCiAgYXMuZGF0YS5mcmFtZSgpIHw+IAogIG11dGF0ZShUaXBvID0gcmVjb2RlKG1vZG8sICAjIHJlY29kZSBpbiBUSSBhbmQgVEMKICAgICAgICAgQmlrZSA9ICJUSW5kaXZpZHVhbCIsCiAgICAgICAgIENhciA9ICJUSW5kaXZpZHVhbCIsCiAgICAgICAgIE1vdG9yY3ljbGUgPSAiVEluZGl2aWR1YWwiLAogICAgICAgICBPdGhlciA9ICJUSW5kaXZpZHVhbCIsCiAgICAgICAgIFRyYW5zaXQgPSAiVENvbGV0aXZvIiwKICAgICAgICAgV2FsayA9ICJUSW5kaXZpZHVhbCIpKSB8PiAKICBncm91cF9ieShPcmlnZW0sIERlc3Rpbm8sIFRpcG8pIHw+IAogIHN1bW1hcmlzZSh2aWFnZW5zID0gc3VtKHZpYWdlbnMpKSB8PiAKICB1bmdyb3VwKCkgfD4gCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IFRpcG8sCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSB2aWFnZW5zKQoKVFJJUFN2c1tpcy5uYShUUklQU3ZzKV0gPSAwICMgaMOhIGNhc29zIGVtIHF1ZSBuw6NvIGjDoSB2aWFnZW5zIHJlZ2lzdGFkYXMgZW50cmUgbXVuaWPDrXBpb3MKVFJJUFN2cyA9IG9kX29uZXdheShUUklQU3ZzKSAjIG1hZ2lhIHBhcmEgc29tYXIgTy1EIGNvbSBELU8KCgprbml0cjo6a2FibGUoaGVhZChUUklQU3ZzKSkgIyB2aWFnZW5zIHNlcGFyYWRhcyBwb3IgVEkgZSBUQwpgYGAKCkEgdG90YWwgb2YgYHIgcm91bmQoc3VtKFRSSVBTYWxsJHZpYWdlbnMpLzEwMDAwMDAsMSlgIG1pbGxpb24gdHJpcHMgYXJlIG1hZGUgZGFpbHkgaW4gdGhlIEFNTCwgb2Ygd2hpY2ggYHIgcm91bmQoc3VtKFRSSVBTaW50ZXIkdmlhZ2VucykvMTAwMClgIHRob3VzYW5kIGFyZSBpbnRlcmNpdHkuCgojIyBHZXQgQU1MIG1hcHMKCmBgYHtyIGFtbGdlb30KTVVOSUNJUElPU2dlbyA9IHJlYWRSRFModXJsKCJodHRwczovL2dpdGh1Yi5jb20vVS1TaGlmdC9iaWNsYXIvcmVsZWFzZXMvZG93bmxvYWQvMC4wLjEvTVVOSUNJUElPU2dlby5SZHMiKSkKTVVOSUNJUElPU2dlbyRDb25jZWxob1tNVU5JQ0lQSU9TZ2VvJENvbmNlbGhvID09ICJTZXR1YmFsIl0gPSAiU2V0w7piYWwiCgpBTUxfZHRjYyA9IHJlYWRSRFModXJsKCJodHRwczovL2dpdGh1Yi5jb20vVS1TaGlmdC9iaWNsYXIvcmVsZWFzZXMvZG93bmxvYWQvMC4wLjEvWk9OQU1FTlRPX2ltb2IuUmRzIikpCkFNTF9kdGNjID0gQU1MX2R0Y2MgfD4gc2VsZWN0KERUTU4sIERUTU5fRFNHKSB8PiB1bmlxdWUoKQoKQ0VOVFJPSURTID0gcmVhZFJEUyh1cmwoImh0dHBzOi8vZ2l0aHViLmNvbS9VLVNoaWZ0L2JpY2xhci9yZWxlYXNlcy9kb3dubG9hZC8wLjAuMS9DRU5UUk9JRFNfbXVuaWNpcGlvcy5SZHMiKSkKQ0VOVFJPSURTID0gQ0VOVFJPSURTIHw+CiAgbGVmdF9qb2luKEFNTF9kdGNjLCBieSA9IGMoIkRUTU4xMSIgPSAiRFRNTiIpKSB8PgogIHNlbGVjdChEVE1OX0RTRywgZ2VvbWV0cnkpIHw+CiAgZmlsdGVyKERUTU5fRFNHICE9ICJNb250aWpvIikKCk1PTlRJSk8gPSBzZjo6c3RfcmVhZCgiZ2VvL01vbnRpam8uZ2VvanNvbiIsIHF1aWV0ID0gVFJVRSkgIyBQb3JxdWUgbyBjZW50cm8gZGFzIGR1YXMgcGFydHMgZG8gTW9udGlqbyBuw6NvIGNhbGhhIGRlbnRybyBkbyBNb250aWpvCkNFTlRST0lEUyA9IHJiaW5kKENFTlRST0lEUywgTU9OVElKTykKYGBgCgojIyBNYWtlIG1hcHMKClVzZSBgc3RwbGFucmAgdG8gY3JlYXRlIHRoZSBbZGVzaXJlIGxpbmVzXShodHRwczovL2RvY3Mucm9wZW5zY2kub3JnL3N0cGxhbnIvcmVmZXJlbmNlL29kMmxpbmUuaHRtbCkuCgpgYGB7ciBvZDJsaW5lfQpMSU5IQVNvZCA9IG9kMmxpbmUoZmxvdyA9IFRSSVBTaW50ZXIsCiAgICAgICAgICAgICAgICAgICB6b25lcyA9IENFTlRST0lEUywKICAgICAgICAgICAgICAgICAgIHpvbmVfY29kZSA9ICJEVE1OX0RTRyIpIHw+IAogIGZpbHRlcih2aWFnZW5zID49IDEwMDApCkxJTkhBU29kX25vTFggPSBMSU5IQVNvZCB8PiBmaWx0ZXIoT3JpZ2VtICE9ICJMaXNib2EiICYgRGVzdGlubyAhPSAiTGlzYm9hIikKCkxJTkhBU29kX1RJID0gb2QybGluZShmbG93ID0gVFJJUFN2cyB8PiBzZWxlY3QoLVRDb2xldGl2byksCiAgICAgICAgICAgICAgICAgICAgICB6b25lcyA9IENFTlRST0lEUywKICAgICAgICAgICAgICAgICAgICAgIHpvbmVfY29kZSA9ICJEVE1OX0RTRyIpIHw+IAogIGZpbHRlcihUSW5kaXZpZHVhbCA+IDEwMDApCkxJTkhBU29kX1RJX25vTFggPSBMSU5IQVNvZF9USSB8PiBmaWx0ZXIoT3JpZ2VtICE9ICJMaXNib2EiICYgRGVzdGlubyAhPSAiTGlzYm9hIikKCkxJTkhBU29kX1RDID0gb2QybGluZShmbG93ID0gVFJJUFN2cyB8PiBzZWxlY3QoLVRJbmRpdmlkdWFsKSwKICAgICAgICAgICAgICAgICAgICAgIHpvbmVzID0gQ0VOVFJPSURTLAogICAgICAgICAgICAgICAgICAgICAgem9uZV9jb2RlID0gIkRUTU5fRFNHIikgfD4gCiAgZmlsdGVyKFRDb2xldGl2byA+IDEwMDApCkxJTkhBU29kX1RDX25vTFggPSBMSU5IQVNvZF9UQyB8PiBmaWx0ZXIoT3JpZ2VtICE9ICJMaXNib2EiICYgRGVzdGlubyAhPSAiTGlzYm9hIikKYGBgCgojIyMgQWxsIFRyaXBzCgojIyMjIEluY2x1ZGluZyBMaXNib24KCmBgYHtyIGludGVybXVuaWNpcGFpc0FMTCwgb3V0LndpZHRoID0gJzEwMCUnfQptMSA9ICB0bV9zaGFwZShNVU5JQ0lQSU9TZ2VvKSArCiAgdG1fYm9yZGVycyhjb2wgPSAiZ3JleSIpICsKICB0bV9zaGFwZShMSU5IQVNvZCAlPiUgZmlsdGVyKHZpYWdlbnMgPj01MDAwKSkgKwogIHRtX2xpbmVzKCJ2aWFnZW5zIiwKICAgICAgICAgICBwYWxldHRlID0gdmlyaWRpczo6bWFnbWEobiA9IDQsIGRpcmVjdGlvbiA9IC0xKSwKICAgICAgICAgICBicmVha3MgPSBjKDUwMDAsIDEwMDAwLCA1MDAwMCwgMTAwMDAwLCAxNjEwMDApLAogICAgICAgICAgIGx3ZCA9ICJ2aWFnZW5zIiwKICAgICAgICAgICBzY2FsZSA9IDMwLAogICAgICAgICAgIHRpdGxlLmNvbCA9ICJWaWFnZW5zIGludGVybXVuaWNpcGFpcyIpICsKICB0bV9zaGFwZShDRU5UUk9JRFMpICsKICB0bV90ZXh0KCJEVE1OX0RTRyIsIHNpemUgPSAwLjgsIGNvbCA9ICJncmF5MjUiKQptMQpgYGAKCiMjIyMgRXhjbHVkaW5nIExpc2JvbgoKYGBge3IgaW50ZXJtdW5pY2lwYWlzc2VtTFgsIG91dC53aWR0aCA9ICcxMDAlJ30KbTIgPSB0bV9zaGFwZShNVU5JQ0lQSU9TZ2VvKSArCiAgdG1fYm9yZGVycyhjb2wgPSAiZ3JleSIpICsKICB0bV9zaGFwZShMSU5IQVNvZF9ub0xYICU+JSBmaWx0ZXIodmlhZ2VucyA+PTMwMDApKSArCiAgdG1fbGluZXMoInZpYWdlbnMiLAogICAgICAgICAgIHBhbGV0dGUgPSB2aXJpZGlzOjptYWdtYShuID0gNCwgZGlyZWN0aW9uID0gLTEpLAogICAgICAgICAgIGJyZWFrcyA9IGMoMzAwMCwgMTAwMDAsIDMwMDAwLCA2MDAwMCwgNzMwMDApLAogICAgICAgICAgIGx3ZCA9ICJ2aWFnZW5zIiwKICAgICAgICAgICBzY2FsZSA9IDMwLAogICAgICAgICAgIHRpdGxlLmNvbCA9ICJWaWFnZW5zIGludGVybXVuaWNpcGFpcywgZm9yYSBkZSBMaXNib2EiKSArCiAgdG1fc2hhcGUoQ0VOVFJPSURTKSArCiAgdG1fdGV4dCgiRFRNTl9EU0ciLCBzaXplID0gMC44LCBjb2wgPSAiZ3JheTI1IikKbTIKYGBgCgojIyMgT25seSBQdWJsaWMgVHJhbnNpdCB0cmlwcwoKIyMjIyBJbmNsdWRpbmcgTGlzYm9uCgpgYGB7ciBpbnRlcm11bmljaXBhaXNfVEMsIG91dC53aWR0aCA9ICcxMDAlJ30KbTMgPSB0bV9zaGFwZShNVU5JQ0lQSU9TZ2VvKSArCiAgdG1fYm9yZGVycyhjb2wgPSAiZ3JleSIpICsKICB0bV9zaGFwZShMSU5IQVNvZF9UQyAlPiUgZmlsdGVyKFRDb2xldGl2byA+PTMwMDApKSArCiAgdG1fbGluZXMoIlRDb2xldGl2byIsCiAgICAgICAgICAgcGFsZXR0ZSA9IHZpcmlkaXM6OnZpcmlkaXMobiA9IDQsIGRpcmVjdGlvbiA9IC0xKSwKICAgICAgICAgICBicmVha3MgPSBjKDMwMDAsIDUwMDAsIDEwMDAwLCAyNTAwMCwgNTAwMDApLAogICAgICAgICAgIGx3ZCA9ICJUQ29sZXRpdm8iLAogICAgICAgICAgIHNjYWxlID0gMzAsCiAgICAgICAgICAgdGl0bGUuY29sID0gIlZpYWdlbnMgaW50ZXJtdW5pY2lwYWlzLCBlbSBUcmFuc3BvcnRlIENvbGV0aXZvIikgKwogIHRtX3NoYXBlKENFTlRST0lEUykgKwogIHRtX3RleHQoIkRUTU5fRFNHIiwgc2l6ZSA9IDAuOCwgY29sID0gImdyYXkyNSIpCm0zCmBgYAoKIyMjIyBFeGNsdWRpbmcgTGlzYm9uCgpgYGB7ciBpbnRlcm11bmljaXBhaXNzZW1MWF9UQywgb3V0LndpZHRoID0gJzEwMCUnfQptNCA9IHRtX3NoYXBlKE1VTklDSVBJT1NnZW8pICsKICB0bV9ib3JkZXJzKGNvbCA9ICJncmV5IikgKwogIHRtX3NoYXBlKExJTkhBU29kX1RDX25vTFggJT4lIGZpbHRlcihUQ29sZXRpdm8gPj0yMDAwKSkgKwogIHRtX2xpbmVzKCJUQ29sZXRpdm8iLAogICAgICAgICAgIHBhbGV0dGUgPSB2aXJpZGlzOjp2aXJpZGlzKG4gPSA0LCBkaXJlY3Rpb24gPSAtMSksCiAgICAgICAgICAgYnJlYWtzID0gYygyMDAwLCA0MDAwLCA3MDAwLCAxMDAwMCwgMTMwMDApLAogICAgICAgICAgIGx3ZCA9ICJUQ29sZXRpdm8iLAogICAgICAgICAgIHNjYWxlID0gMzAsCiAgICAgICAgICAgdGl0bGUuY29sID0gIlZpYWdlbnMgaW50ZXJtdW5pY2lwYWlzLCBlbSBUcmFuc3BvcnRlIENvbGV0aXZvIChmb3JhIEx4KSIpICsKICB0bV9zaGFwZShDRU5UUk9JRFMpICsKICB0bV90ZXh0KCJEVE1OX0RTRyIsIHNpemUgPSAwLjgsIGNvbCA9ICJncmF5MjUiKQptNApgYGAKCgojIyMgT25seSBQcml2YXRlIHRyaXBzCgojIyMjIEluY2x1ZGluZyBMaXNib24KCmBgYHtyIGludGVybXVuaWNpcGFpc19USSwgb3V0LndpZHRoID0gJzEwMCUnfQptNSA9IHRtX3NoYXBlKE1VTklDSVBJT1NnZW8pICsKICB0bV9ib3JkZXJzKGNvbCA9ICJncmV5IikgKwogIHRtX3NoYXBlKExJTkhBU29kX1RJICU+JSBmaWx0ZXIoVEluZGl2aWR1YWwgPj01MDAwKSkgKwogIHRtX2xpbmVzKCJUSW5kaXZpZHVhbCIsCiAgICAgICAgICAgcGFsZXR0ZSA9IHZpcmlkaXM6OnBsYXNtYShuID0gNCwgZGlyZWN0aW9uID0gLTEpLAogICAgICAgICAgIGJyZWFrcyA9IGMoNTAwMCwgMjAwMDAsIDUwMDAwLCAxMDAwMDAsIDExNTAwMCksCiAgICAgICAgICAgbHdkID0gIlRJbmRpdmlkdWFsIiwKICAgICAgICAgICBzY2FsZSA9IDMwLAogICAgICAgICAgIHRpdGxlLmNvbCA9ICJWaWFnZW5zIGludGVybXVuaWNpcGFpcywgZW0gVHJhbnNwb3J0ZSBJbmRpdmlkdWFsIikgKwogIHRtX3NoYXBlKENFTlRST0lEUykgKwogIHRtX3RleHQoIkRUTU5fRFNHIiwgc2l6ZSA9IDAuOCwgY29sID0gImdyYXkyNSIpCm01CmBgYAoKIyMjIyBFeGNsdWRpbmcgTGlzYm9uCgpgYGB7ciBpbnRlcm11bmljaXBhaXNzZW1MWF9USSwgb3V0LndpZHRoID0gJzEwMCUnfQptNiA9IHRtX3NoYXBlKE1VTklDSVBJT1NnZW8pICsKICB0bV9ib3JkZXJzKGNvbCA9ICJncmV5IikgKwogIHRtX3NoYXBlKExJTkhBU29kX1RJX25vTFggJT4lIGZpbHRlcihUSW5kaXZpZHVhbCA+PTMwMDApKSArCiAgdG1fbGluZXMoIlRJbmRpdmlkdWFsIiwKICAgICAgICAgICBwYWxldHRlID0gdmlyaWRpczo6cGxhc21hKG4gPSA0LCBkaXJlY3Rpb24gPSAtMSksCiAgICAgICAgICAgYnJlYWtzID0gYygzMDAwLCAxMDAwMCwgMjUwMDAsIDUwMDAwLCA2NTAwMCksCiAgICAgICAgICAgbHdkID0gIlRJbmRpdmlkdWFsIiwKICAgICAgICAgICBzY2FsZSA9IDMwLAogICAgICAgICAgIHRpdGxlLmNvbCA9ICJWaWFnZW5zIGludGVybXVuaWNpcGFpcywgZW0gVHJhbnNwb3J0ZSBJbmRpdmlkdWFsIChmb3JhIEx4KSIpICsKICB0bV9zaGFwZShDRU5UUk9JRFMpICsKICB0bV90ZXh0KCJEVE1OX0RTRyIsIHNpemUgPSAwLjgsIGNvbCA9ICJncmF5MjUiKQptNgpgYGAK